package io.gitee.wolfmusic.jarlibrary.mojos;

import io.gitee.wolfmusic.jarlibrary.config.ArtifactConfig;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;
import org.apache.maven.project.MavenProject;

import java.io.*;
import java.nio.file.Files;
import java.util.List;

/**
 * @author langle__
 * @version 1.0
 */
@Mojo(name = "run", defaultPhase = LifecyclePhase.GENERATE_RESOURCES, requiresDependencyResolution = ResolutionScope.TEST)
public class RunMojo extends AbstractMojo {

    @Parameter(defaultValue = "${project}", readonly = true, required = true)
    private MavenProject mavenProject;

    @Parameter(property = "filters")
    private List<ArtifactConfig> filters;

    @Parameter(defaultValue = "${project.build.outputDirectory}/library")
    private String libraryPath;

    @Parameter(defaultValue = "${project.build.outputDirectory}/library/library")
    private String dependenciesPath;

    @Override
    public void execute() throws MojoExecutionException, MojoFailureException {
        Log log = getLog();

        Writer writer;
        try {
            File dependenciesFile = new File(dependenciesPath);
            File parentDir = dependenciesFile.getParentFile();
            if (parentDir != null && !parentDir.exists() && !parentDir.mkdirs()) {
                log.error("Failed to create directory: " + parentDir.getAbsolutePath());
                return;
            }
            if (!dependenciesFile.createNewFile()) {
                log.error("Failed to create dependencies file: " + dependenciesFile.getAbsolutePath());
                return;
            }
            writer = new FileWriter(dependenciesFile);
        } catch (IOException e) {
            log.error("Failed to create dependencies file: " + e.getMessage());
            return;
        }

        File library = new File(libraryPath);
        if (library.exists()) {
            File[] files = library.listFiles(f -> f.isFile() && f.getName().endsWith(".jar"));
            if (files != null) {
                for (File file : files) {
                    if (!file.delete()) {
                        log.warn("Could not delete: " + file.getAbsolutePath());
                    }
                }
            }
        } else if (!library.mkdirs()) {
            log.error("Could not create directory: " + library.getAbsolutePath());
        }

        for (Artifact artifact : mavenProject.getArtifacts()) {
            String type = artifact.getType().toLowerCase();
            if (type.equals("pom")) continue;
            String scope = artifact.getScope();
            if (scope.equals("provided") || scope.equals("test")) continue;

            if (isFilterDependency(artifact)) continue;

            File file = artifact.getFile();
            File toFile = new File(library, file.getName());

            try {
                Files.copy(file.toPath(), toFile.toPath());
                writer.write(file.getName() + "\n");
            } catch (IOException e) {
                log.error(e.getMessage());
            }
        }
        try {
            writer.flush();
            writer.close();
        } catch (IOException e) {
            log.error(e.getMessage());
        }
    }

    private boolean isFilterDependency(Artifact artifact) {
        if (artifact == null || filters == null || filters.isEmpty()) return false;

        String groupId = artifact.getGroupId();
        String artifactId = artifact.getArtifactId();

        for (ArtifactConfig config : filters) {
            if (groupId.equals(config.getGroupId()) && artifactId.equals(config.getArtifactId())) return true;
        }

        return false;
    }

}
